//
//  YDDDeviceInfo.m
//  yddSweet
//
//  Created by Dev on 2024/8/15.
//

#import "YDDDeviceInfo.h"
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import <sys/sysctl.h>
#import <SystemConfiguration/CaptiveNetwork.h>
#import "sys/utsname.h"
#import <mach/mach.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <ifaddrs.h>
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import <CoreTelephony/CTCarrier.h>
#import <SystemConfiguration/SCNetworkReachability.h>
#import <sys/mount.h>

@implementation YDDDeviceInfo

+ (void)load {
    NSString *uuid_ydd = [NSUserDefaults.standardUserDefaults objectForKey:@"YDDDeviceInfo_UUID_ydd"];
    if (uuid_ydd.length) {
        return;
    }
    [NSUserDefaults.standardUserDefaults setObject:NSUUID.UUID.UUIDString forKey:@"YDDDeviceInfo_UUID_ydd"];
    [NSUserDefaults.standardUserDefaults synchronize];
}

/// 设备唯一标识符（卸载后无效，基于NSUserDefaults）
+ (NSString *)uuid_ydd {
    return [NSUserDefaults.standardUserDefaults objectForKey:@"YDDDeviceInfo_UUID_ydd"];
}

/// 获取音频文件的个数
+ (NSInteger)yddGetAudioCount {
    NSDirectoryEnumerator *urls_ydd = [NSFileManager.new enumeratorAtURL:[NSURL URLWithString:@"/System/Library/Audio"] includingPropertiesForKeys:@[NSURLIsDirectoryKey] options:0 errorHandler:^BOOL(NSURL * _Nonnull url, NSError * _Nonnull error) {
        return true;
    }];
    NSInteger count_ydd = 0;
    for (NSURL *url_ydd in urls_ydd) {
        NSNumber *is_directory_ydd = nil;
        [url_ydd getResourceValue:&is_directory_ydd forKey:NSURLIsDirectoryKey error:nil];
        if (is_directory_ydd && [is_directory_ydd boolValue]) {
            count_ydd += 1;
        }
    }
    return count_ydd;
}

/// 获取视频文件的个数
+ (NSInteger)yddGetVideoCount {
    NSDirectoryEnumerator *urls_ydd = [NSFileManager.new enumeratorAtURL:[NSURL URLWithString:@"/System/Library/Video"] includingPropertiesForKeys:@[NSURLIsDirectoryKey] options:0 errorHandler:^BOOL(NSURL * _Nonnull url, NSError * _Nonnull error) {
        return true;
    }];
    NSInteger count_ydd = 0;
    for (NSURL *url_ydd in urls_ydd) {
        NSNumber *is_directory_ydd = nil;
        [url_ydd getResourceValue:&is_directory_ydd forKey:NSURLIsDirectoryKey error:nil];
        if (is_directory_ydd && [is_directory_ydd boolValue]) {
            count_ydd += 1;
        }
    }
    return count_ydd;
}

/// 获取设备是否设置了代理
+ (BOOL)yddGetProxyStatusWithDomain:(NSString *)domain_ydd {
    NSDictionary *proxySettings_ydd = (__bridge NSDictionary *)(CFNetworkCopySystemProxySettings());
    NSArray *proxies_ydd = (__bridge NSArray *)(CFNetworkCopyProxiesForURL((__bridge CFURLRef _Nonnull)([NSURL URLWithString:domain_ydd]), (__bridge CFDictionaryRef _Nonnull)(proxySettings_ydd)));
    NSDictionary *settings_ydd = [proxies_ydd objectAtIndex:0];
    if ([[settings_ydd objectForKey:(NSString *)kCFProxyTypeKey] isEqualToString:@"kCFProxyTypeNone"]) {
        return NO;
    }
    return YES;
}

/// 获取设备是否设置了VPN
+ (BOOL)yddIsVPNEnabled {
    NSInteger vpnActive_ydd = 0;
    struct ifaddrs *interfaces_ydd = NULL;
    struct ifaddrs *addr_ydd = NULL;
    int family_ydd, s_ydd;
    if (getifaddrs(&interfaces_ydd) == 0) {
        for (addr_ydd = interfaces_ydd; addr_ydd != NULL; addr_ydd = addr_ydd->ifa_next) {
            if (addr_ydd->ifa_addr && addr_ydd->ifa_addr->sa_family == AF_INET) {
                family_ydd = AF_INET;
            } else if (addr_ydd->ifa_addr && addr_ydd->ifa_addr->sa_family == AF_INET6) {
                family_ydd = AF_INET6;
            } else {
                continue;
            }
            if (strncmp(addr_ydd->ifa_name, "tun", 3) == 0 || strncmp(addr_ydd->ifa_name, "ppp", 3) == 0) {
                vpnActive_ydd = 1;
                break;
            }
        }
        freeifaddrs(interfaces_ydd);
    }
    return vpnActive_ydd;
}

/// cpu核数
+ (NSUInteger)yddGetNumberOfCPUCores {
    size_t size;
    int nm[2];
    nm[0] = CTL_HW;
    nm[1] = HW_NCPU;
    size = sizeof(uint32_t);
    uint32_t numCPUs;
    if (sysctl(nm, 2, &numCPUs, &size, NULL, 0) < 0) {
        perror("sysctl");
        numCPUs = 0;
    }
    return numCPUs;
}

/// 是否是模拟器
+ (NSInteger)yddIsSimulator {
    #if TARGET_OS_SIMULATOR
        return 1;
    #else
        return 0;
    #endif
}

/// 获取设备型号
+ (NSString *)yddGetDeviceIdentifier {
    struct utsname systemInfo_ydd;
    uname(&systemInfo_ydd);
    NSString *platform_ydd = [NSString stringWithCString:systemInfo_ydd.machine encoding:NSUTF8StringEncoding];
    // iPhone
    if ([platform_ydd isEqualToString:@"iPhone1,1"]) return @"iPhone 2G";
    if ([platform_ydd isEqualToString:@"iPhone1,2"]) return @"iPhone 3G";
    if ([platform_ydd isEqualToString:@"iPhone2,1"]) return @"iPhone 3GS";
    if ([platform_ydd isEqualToString:@"iPhone3,1"]) return @"iPhone 4";
    if ([platform_ydd isEqualToString:@"iPhone3,2"]) return @"iPhone 4";
    if ([platform_ydd isEqualToString:@"iPhone3,3"]) return @"iPhone 4";
    if ([platform_ydd isEqualToString:@"iPhone4,1"]) return @"iPhone 4S";
    if ([platform_ydd isEqualToString:@"iPhone5,1"]) return @"iPhone 5";
    if ([platform_ydd isEqualToString:@"iPhone5,2"]) return @"iPhone 5";
    if ([platform_ydd isEqualToString:@"iPhone5,3"]) return @"iPhone 5c";
    if ([platform_ydd isEqualToString:@"iPhone5,4"]) return @"iPhone 5c";
    if ([platform_ydd isEqualToString:@"iPhone6,1"]) return @"iPhone 5s";
    if ([platform_ydd isEqualToString:@"iPhone6,2"]) return @"iPhone 5s";
    if ([platform_ydd isEqualToString:@"iPhone7,1"]) return @"iPhone 6 Plus";
    if ([platform_ydd isEqualToString:@"iPhone7,2"]) return @"iPhone 6";
    if ([platform_ydd isEqualToString:@"iPhone8,1"]) return @"iPhone 6s";
    if ([platform_ydd isEqualToString:@"iPhone8,2"]) return @"iPhone 6s Plus";
    if ([platform_ydd isEqualToString:@"iPhone8,4"]) return @"iPhone SE 1";
    if ([platform_ydd isEqualToString:@"iPhone9,1"]) return @"iPhone 7";
    if ([platform_ydd isEqualToString:@"iPhone9,3"]) return @"iPhone 7";
    if ([platform_ydd isEqualToString:@"iPhone9,2"]) return @"iPhone 7 Plus";
    if ([platform_ydd isEqualToString:@"iPhone9,4"]) return @"iPhone 7 Plus";
    if ([platform_ydd isEqualToString:@"iPhone10,1"]) return @"iPhone 8";
    if ([platform_ydd isEqualToString:@"iPhone10,4"]) return @"iPhone 8";
    if ([platform_ydd isEqualToString:@"iPhone10,2"]) return @"iPhone 8 Plus";
    if ([platform_ydd isEqualToString:@"iPhone10,5"]) return @"iPhone 8 Plus";
    if ([platform_ydd isEqualToString:@"iPhone10,3"]) return @"iPhone X";
    if ([platform_ydd isEqualToString:@"iPhone10,6"]) return @"iPhone X";
    if ([platform_ydd isEqualToString:@"iPhone11,2"]) return @"iPhone XS";
    if ([platform_ydd isEqualToString:@"iPhone11,4"]) return @"iPhone XS MAX";
    if ([platform_ydd isEqualToString:@"iPhone11,6"]) return @"iPhone XS MAX";
    if ([platform_ydd isEqualToString:@"iPhone11,8"]) return @"iPhone XR";
    if ([platform_ydd isEqualToString:@"iPhone12,1"]) return @"iPhone 11";
    if ([platform_ydd isEqualToString:@"iPhone12,3"]) return @"iPhone 11 Pro";
    if ([platform_ydd isEqualToString:@"iPhone12,5"]) return @"iPhone 11 Pro Max";
    if ([platform_ydd isEqualToString:@"iPhone12,8"]) return @"iPhone SE 2";
    if ([platform_ydd isEqualToString:@"iPhone13,1"]) return @"iPhone 12 mini";
    if ([platform_ydd isEqualToString:@"iPhone13,2"]) return @"iPhone 12";
    if ([platform_ydd isEqualToString:@"iPhone13,3"]) return @"iPhone 12 Pro";
    if ([platform_ydd isEqualToString:@"iPhone13,4"]) return @"iPhone 12 Pro Max";
    if ([platform_ydd isEqualToString:@"iPhone14,4"]) return @"iPhone 13 mini";
    if ([platform_ydd isEqualToString:@"iPhone14,5"]) return @"iPhone 13";
    if ([platform_ydd isEqualToString:@"iPhone14,2"]) return @"iPhone 13 Pro";
    if ([platform_ydd isEqualToString:@"iPhone14,3"]) return @"iPhone 13 Pro Max";
    if ([platform_ydd isEqualToString:@"iPhone14,6"]) return @"iPhone SE 3";
    if ([platform_ydd isEqualToString:@"iPhone14,7"]) return @"iPhone 14";
    if ([platform_ydd isEqualToString:@"iPhone14,8"]) return @"iPhone 14 Plus";
    if ([platform_ydd isEqualToString:@"iPhone15,2"]) return @"iPhone 14 Pro";
    if ([platform_ydd isEqualToString:@"iPhone15,3"]) return @"iPhone 14 Pro Max";
    
    
    // iPod
    if ([platform_ydd isEqualToString:@"iPod1,1"])  return @"iPod Touch 1";
    if ([platform_ydd isEqualToString:@"iPod2,1"])  return @"iPod Touch 2";
    if ([platform_ydd isEqualToString:@"iPod3,1"])  return @"iPod Touch 3";
    if ([platform_ydd isEqualToString:@"iPod4,1"])  return @"iPod Touch 4";
    if ([platform_ydd isEqualToString:@"iPod5,1"])  return @"iPod Touch 5";
    if ([platform_ydd isEqualToString:@"iPod7,1"])  return @"iPod Touch 6";
    if ([platform_ydd isEqualToString:@"iPod9,1"])  return @"iPod Touch 7";
    
    // iPad
    if ([platform_ydd isEqualToString:@"iPad1,1"])  return @"iPad 1";
    if ([platform_ydd isEqualToString:@"iPad2,1"])  return @"iPad 2";
    if ([platform_ydd isEqualToString:@"iPad2,2"]) return @"iPad 2";
    if ([platform_ydd isEqualToString:@"iPad2,3"])  return @"iPad 2";
    if ([platform_ydd isEqualToString:@"iPad2,4"])  return @"iPad 2";
    if ([platform_ydd isEqualToString:@"iPad2,5"])  return @"iPad Mini 1";
    if ([platform_ydd isEqualToString:@"iPad2,6"])  return @"iPad Mini 1";
    if ([platform_ydd isEqualToString:@"iPad2,7"])  return @"iPad Mini 1";
    if ([platform_ydd isEqualToString:@"iPad3,1"])  return @"iPad 3";
    if ([platform_ydd isEqualToString:@"iPad3,2"])  return @"iPad 3";
    if ([platform_ydd isEqualToString:@"iPad3,3"])  return @"iPad 3";
    if ([platform_ydd isEqualToString:@"iPad3,4"])  return @"iPad 4";
    if ([platform_ydd isEqualToString:@"iPad3,5"])  return @"iPad 4";
    if ([platform_ydd isEqualToString:@"iPad3,6"])  return @"iPad 4";
    if ([platform_ydd isEqualToString:@"iPad4,1"])  return @"iPad Air";
    if ([platform_ydd isEqualToString:@"iPad4,2"])  return @"iPad Air";
    if ([platform_ydd isEqualToString:@"iPad4,3"])  return @"iPad Air";
    if ([platform_ydd isEqualToString:@"iPad4,4"])  return @"iPad mini 2";
    if ([platform_ydd isEqualToString:@"iPad4,5"])  return @"iPad mini 2";
    if ([platform_ydd isEqualToString:@"iPad4,6"])  return @"iPad mini 2";
    if ([platform_ydd isEqualToString:@"iPad4,7"])  return @"iPad mini 3";
    if ([platform_ydd isEqualToString:@"iPad4,8"])  return @"iPad mini 3";
    if ([platform_ydd isEqualToString:@"iPad4,9"])  return @"iPad mini 3";
    if ([platform_ydd isEqualToString:@"iPad5,1"])  return @"iPad mini 4";
    if ([platform_ydd isEqualToString:@"iPad5,2"])  return @"iPad mini 4";
    if ([platform_ydd isEqualToString:@"iPad5,3"])  return @"iPad Air 2";
    if ([platform_ydd isEqualToString:@"iPad5,4"])  return @"iPad Air 2";
    if ([platform_ydd isEqualToString:@"iPad6,3"])  return @"iPad Pro (9.7-inch)";
    if ([platform_ydd isEqualToString:@"iPad6,4"])  return @"iPad Pro (9.7-inch)";
    if ([platform_ydd isEqualToString:@"iPad6,7"])  return @"iPad Pro (12.9-inch)";
    if ([platform_ydd isEqualToString:@"iPad6,8"])  return @"iPad Pro (12.9-inch)";
    if ([platform_ydd isEqualToString:@"iPad6,11"])  return @"iPad 5";
    if ([platform_ydd isEqualToString:@"iPad6,12"])  return @"iPad 5";
    if ([platform_ydd isEqualToString:@"iPad7,1"])  return @"iPad Pro 2(12.9-inch)";
    if ([platform_ydd isEqualToString:@"iPad7,2"])  return @"iPad Pro 2(12.9-inch)";
    if ([platform_ydd isEqualToString:@"iPad7,3"])  return @"iPad Pro (10.5-inch)";
    if ([platform_ydd isEqualToString:@"iPad7,4"])  return @"iPad Pro (10.5-inch)";
    if ([platform_ydd isEqualToString:@"iPad7,5"])  return @"iPad 6";
    if ([platform_ydd isEqualToString:@"iPad7,6"])  return @"iPad 6";
    if ([platform_ydd isEqualToString:@"iPad7,11"])  return @"iPad 7";
    if ([platform_ydd isEqualToString:@"iPad7,12"])  return @"iPad 7";
    if ([platform_ydd isEqualToString:@"iPad8,1"])  return @"iPad Pro (11-inch) ";
    if ([platform_ydd isEqualToString:@"iPad8,2"])  return @"iPad Pro (11-inch) ";
    if ([platform_ydd isEqualToString:@"iPad8,3"])  return @"iPad Pro (11-inch) ";
    if ([platform_ydd isEqualToString:@"iPad8,4"])  return @"iPad Pro (11-inch) ";
    if ([platform_ydd isEqualToString:@"iPad8,5"])  return @"iPad Pro 3 (12.9-inch) ";
    if ([platform_ydd isEqualToString:@"iPad8,6"])  return @"iPad Pro 3 (12.9-inch) ";
    if ([platform_ydd isEqualToString:@"iPad8,7"])  return @"iPad Pro 3 (12.9-inch) ";
    if ([platform_ydd isEqualToString:@"iPad8,8"])  return @"iPad Pro 3 (12.9-inch) ";
    if ([platform_ydd isEqualToString:@"iPad8,9"])  return @"iPad Pro 2 (11-inch) ";
    if ([platform_ydd isEqualToString:@"iPad8,10"])  return @"iPad Pro 2 (11-inch) ";
    if ([platform_ydd isEqualToString:@"iPad8,11"])  return @"iPad Pro 4 (12.9-inch) ";
    if ([platform_ydd isEqualToString:@"iPad8,12"])  return @"iPad Pro 4 (12.9-inch) ";
    if ([platform_ydd isEqualToString:@"iPad11,1"])  return @"iPad mini 5";
    if ([platform_ydd isEqualToString:@"iPad11,2"])  return @"iPad mini 5";
    if ([platform_ydd isEqualToString:@"iPad11,3"])  return @"iPad Air 3";
    if ([platform_ydd isEqualToString:@"iPad11,4"])  return @"iPad Air 3";
    if ([platform_ydd isEqualToString:@"iPad11,6"])  return @"iPad 8";
    if ([platform_ydd isEqualToString:@"iPad11,7"])  return @"iPad 8";
    if ([platform_ydd isEqualToString:@"iPad12,1"])  return @"iPad 9";
    if ([platform_ydd isEqualToString:@"iPad12,2"])  return @"iPad 9";
    if ([platform_ydd isEqualToString:@"iPad13,1"])  return @"iPad Air 4";
    if ([platform_ydd isEqualToString:@"iPad13,2"])  return @"iPad Air 4";
    if ([platform_ydd isEqualToString:@"iPad13,4"])  return @"iPad Pro 4 (11-inch) ";
    if ([platform_ydd isEqualToString:@"iPad13,5"])  return @"iPad Pro 4 (11-inch) ";
    if ([platform_ydd isEqualToString:@"iPad13,6"])  return @"iPad Pro 4 (11-inch) ";
    if ([platform_ydd isEqualToString:@"iPad13,7"])  return @"iPad Pro 4 (11-inch) ";
    if ([platform_ydd isEqualToString:@"iPad13,8"])  return @"iPad Pro 5 (12.9-inch) ";
    if ([platform_ydd isEqualToString:@"iPad13,9"])  return @"iPad Pro 5 (12.9-inch) ";
    if ([platform_ydd isEqualToString:@"iPad13,10"])  return @"iPad Pro 5 (12.9-inch) ";
    if ([platform_ydd isEqualToString:@"iPad13,11"])  return @"iPad Pro 5 (12.9-inch) ";
    if ([platform_ydd isEqualToString:@"iPad13,18"])  return @"iPad 10";
    if ([platform_ydd isEqualToString:@"iPad13,19"])  return @"iPad 10";
    if ([platform_ydd isEqualToString:@"iPad14,1"])  return @"iPad mini 6";
    if ([platform_ydd isEqualToString:@"iPad14,2"])  return @"iPad mini 6";
    
    // 其他
    if ([platform_ydd isEqualToString:@"i386"])   return @"iPhone Simulator";
    if ([platform_ydd isEqualToString:@"x86_64"])  return @"iPhone Simulator";
    
    return platform_ydd;
}

/// 总空间
+ (NSString *)yddTotalDiskSpace {
    long long space_ydd = [[[[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:nil] objectForKey:NSFileSystemSize] longLongValue];
    return [NSString stringWithFormat:@"%lld",space_ydd];
}

/// 可用空间
+ (NSString *)yddFreeDiskSpace {
    long long freeSpace_ydd = [[[[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:nil] objectForKey:NSFileSystemFreeSize] longLongValue];
    return [NSString stringWithFormat:@"%lld",freeSpace_ydd];
}

/// 已使用空间
+ (NSString *)yddUsedDiskSpace {
    long long totalDiskSpaceInBytes_ydd = [[[[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:nil] objectForKey:NSFileSystemSize] longLongValue];
    long long freeDiskSpaceInBytes_ydd = [[[[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:nil] objectForKey:NSFileSystemFreeSize] longLongValue];
    long long usedDiskSpace_ydd = totalDiskSpaceInBytes_ydd - freeDiskSpaceInBytes_ydd;
    return [NSString stringWithFormat:@"%lld",usedDiskSpace_ydd];
}

+ (NSString *)yddStorage {
    struct statfs storage_info_ydd;
    unsigned long long disk_capacity_ydd = -1;
    if (statfs("/var", &storage_info_ydd) >= 0) {
        disk_capacity_ydd = (unsigned long long)(storage_info_ydd.f_bsize * storage_info_ydd.f_blocks);
    }
    return [NSString stringWithFormat:@"%lld", disk_capacity_ydd];
}

// 已使用的内存空间
+ (NSString *)yddUsedMemory {
    mach_port_t current_host_port_ydd = mach_host_self();
    mach_msg_type_number_t vm_stats_size_ydd = sizeof(vm_statistics_data_t) / sizeof(integer_t);
    vm_size_t page_size_ydd;
    vm_statistics_data_t mem_stats_ydd;
    kern_return_t kern_result_ydd;
    kern_result_ydd = host_page_size(current_host_port_ydd, &page_size_ydd);
    if (kern_result_ydd!= KERN_SUCCESS) return @"-1";
    kern_result_ydd = host_statistics(current_host_port_ydd, HOST_VM_INFO, (host_info_t)&mem_stats_ydd, &vm_stats_size_ydd);
    if (kern_result_ydd!= KERN_SUCCESS) return @"-1";
    return [NSString stringWithFormat:@"%ld", page_size_ydd * (mem_stats_ydd.active_count + mem_stats_ydd.inactive_count + mem_stats_ydd.wire_count)];
}

// 空闲的内存空间,:未使用的 RAM 容量，随时可以被应用分配使用。（感觉本方法和腾讯bugly崩溃统计中的可用内存大小相似）
+ (NSString *)yddFreeMemory {
    mach_port_t current_host_port_ydd = mach_host_self();
    mach_msg_type_number_t vm_stats_size_ydd = sizeof(vm_statistics_data_t) / sizeof(integer_t);
    vm_size_t page_size_ydd;
    vm_statistics_data_t mem_stats_ydd;
    kern_return_t kern_result_ydd;
    kern_result_ydd = host_page_size(current_host_port_ydd, &page_size_ydd);
    if (kern_result_ydd!= KERN_SUCCESS) return @"-1";
    kern_result_ydd = host_statistics(current_host_port_ydd, HOST_VM_INFO, (host_info_t)&mem_stats_ydd, &vm_stats_size_ydd);
    if (kern_result_ydd!= KERN_SUCCESS) return @"-1";
    return [NSString stringWithFormat:@"%ld", mem_stats_ydd.free_count * page_size_ydd];
}

+ (NSString *)yddUnuseStorage {
    vm_statistics_data_t mem_stats_ydd;
    mach_msg_type_number_t vm_info_count_ydd = HOST_VM_INFO_COUNT;
    kern_return_t host_stats_result_ydd = host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&mem_stats_ydd, &vm_info_count_ydd);
    if (host_stats_result_ydd!= KERN_SUCCESS) {
        // 可以添加错误日志记录
        return @"0";
    }
    return [NSString stringWithFormat:@"%ld", ((vm_page_size * mem_stats_ydd.free_count + vm_page_size * mem_stats_ydd.inactive_count))];
}

// 可释放的内存空间：内存吃紧自动释放，针对大对象存放所需的大块内存空间
+ (NSString *)yddPurgableMemory {
    mach_port_t current_host_port_ydd = mach_host_self();
    mach_msg_type_number_t vm_stats_size_ydd = sizeof(vm_statistics_data_t) / sizeof(integer_t);
    vm_size_t page_size_ydd;
    vm_statistics_data_t mem_stats_ydd;
    kern_return_t kern_result_ydd;
    
    kern_result_ydd = host_page_size(current_host_port_ydd, &page_size_ydd);
    if (kern_result_ydd!= KERN_SUCCESS) return @"-1";
    kern_result_ydd = host_statistics(current_host_port_ydd, HOST_VM_INFO, (host_info_t)&mem_stats_ydd, &vm_stats_size_ydd);
    if (kern_result_ydd!= KERN_SUCCESS) return @"-1";
    return [NSString stringWithFormat:@"%ld", mem_stats_ydd.purgeable_count * page_size_ydd];
}

/// wifi名称 获取不到传空
+ (NSString *)yddGetWiFiName {
    NSArray *ifs_ydd = (__bridge_transfer id)CNCopySupportedInterfaces();
    id info_ydd = nil;
    for (NSString *ifnam_ydd in ifs_ydd) {
        info_ydd = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam_ydd);
        if (info_ydd && [info_ydd count]) { break; }
    }
    NSString *wifi_name = [(NSDictionary*)info_ydd objectForKey:@"SSID"];
    return wifi_name ? wifi_name : @"";
}

/// 可清理内存
+ (NSString *)yddFreeMemoryInBytes {
    vm_size_t pageSize_ydd;
    vm_statistics_data_t vmStats_ydd;
    pageSize_ydd = getpagesize();
    mach_msg_type_number_t infoCount_ydd = HOST_VM_INFO_COUNT;
    kern_return_t kernReturn_ydd = host_page_size(mach_host_self(), &pageSize_ydd);
    if (kernReturn_ydd == KERN_SUCCESS) {
        kernReturn_ydd = host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmStats_ydd, &infoCount_ydd);
    }
    if (kernReturn_ydd != KERN_SUCCESS) {
        return @"0";
    }
    uint64_t freeMemory_ydd = vmStats_ydd.free_count * pageSize_ydd;
    return [NSString stringWithFormat:@"%llu", freeMemory_ydd];
}

/// 不活动内存大小
+ (NSString *)yddGetInactiveMemorySizeInBytes {
    mach_msg_type_number_t infoCount_ydd = HOST_VM_INFO_COUNT;
    vm_size_t pageSize_ydd;
    vm_statistics_data_t vmStats_ydd;
    if (host_page_size(mach_host_self(), &pageSize_ydd) != KERN_SUCCESS) {
        return @"Error";
    }
    if (host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmStats_ydd, &infoCount_ydd) != KERN_SUCCESS) {
        return @"Error";
    }
    uint64_t inactive_ydd = vmStats_ydd.inactive_count * pageSize_ydd;
    return [NSString stringWithFormat:@"%llu", inactive_ydd];
}

/// 活动内存大小
+ (NSString *)yddGetCurrentMemoryUsageInBytes {
    mach_msg_type_number_t infoCount_ydd = TASK_VM_INFO_COUNT;
    task_vm_info_data_t vmInfo_ydd;
    kern_return_t kernelReturn_ydd = task_info(mach_task_self(), TASK_VM_INFO, (task_info_t)&vmInfo_ydd, &infoCount_ydd);
    if (kernelReturn_ydd == KERN_SUCCESS) {
        return [NSString stringWithFormat:@"%llu",vmInfo_ydd.phys_footprint]; // 活动内存大小
    }
    return @"";
}

/// 保留内存 单位Byte
+ (NSString *)yddGetWiredMemorySizeInBytes {
    double wiredMemory_ydd = 0.00;
    vm_statistics_data_t vmStats_ydd;
    mach_msg_type_number_t infoCount_ydd = HOST_VM_INFO_COUNT;
    kern_return_t kernReturn = host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmStats_ydd, &infoCount_ydd);
    if(kernReturn!= KERN_SUCCESS) {
        return @"0";
    }
    wiredMemory_ydd = (vm_page_size * vmStats_ydd.wire_count);
    return [NSString stringWithFormat:@"%lld", (long long)wiredMemory_ydd];
}

/// 开机时间到现在的毫秒数（包括睡眠时间）
+ (NSInteger)yddGetElapsedMillisecondsSinceBootAsInteger {
    mach_timebase_info_data_t timebaseInfo_ydd;
    mach_timebase_info(&timebaseInfo_ydd);
    uint64_t currentTime_ydd = mach_absolute_time();
    double nanoseconds_ydd = (double)currentTime_ydd * timebaseInfo_ydd.numer / timebaseInfo_ydd.denom;
    return (NSInteger)(nanoseconds_ydd / 1000000.0);
}

/// 获取mac地址
+ (NSString *)yddMacAddress {
    int                    mib_ydd[6];
    size_t                len_ydd;
    char                *buf_ydd;
    unsigned char        *ptr_ydd;
    struct if_msghdr    *ifm_ydd;
    struct sockaddr_dl    *sdl_ydd;
    mib_ydd[0] = CTL_NET;
    mib_ydd[1] = AF_ROUTE;
    mib_ydd[2] = 0;
    mib_ydd[3] = AF_LINK;
    mib_ydd[4] = NET_RT_IFLIST;
    if ((mib_ydd[5] = if_nametoindex("en0")) == 0) {
        return @"02:00:00:00:00:00";
    }
    if (sysctl(mib_ydd, 6, NULL, &len_ydd, NULL, 0) < 0) {
        return @"02:00:00:00:00:00";
    }
    if ((buf_ydd = malloc(len_ydd)) == NULL) {
        return @"02:00:00:00:00:00";
    }
    if (sysctl(mib_ydd, 6, buf_ydd, &len_ydd, NULL, 0) < 0) {
        return @"02:00:00:00:00:00";
    }
    ifm_ydd = (struct if_msghdr *)buf_ydd;
    sdl_ydd = (struct sockaddr_dl *)(ifm_ydd + 1);
    ptr_ydd = (unsigned char *)LLADDR(sdl_ydd);
    NSString *outstring_ydd = [NSString stringWithFormat:@"%02x:%02x:%02x:%02x:%02x:%02x", *ptr_ydd, *(ptr_ydd+1), *(ptr_ydd+2), *(ptr_ydd+3), *(ptr_ydd+4), *(ptr_ydd+5)];
    free(buf_ydd);
    return [outstring_ydd uppercaseString];
}

/// 获取当前设备运营商无线接入技术
+ (NSString *)yddGetCurrentCarrierRadioAccessTechnology {
    CTTelephonyNetworkInfo *networkInfo_ydd = [[CTTelephonyNetworkInfo alloc] init];
    if (networkInfo_ydd.serviceCurrentRadioAccessTechnology.allValues.count > 0) {
        return networkInfo_ydd.serviceCurrentRadioAccessTechnology.allValues.firstObject;
    }
    return @"";
}

/// 上次活跃时间戳(秒)
+ (NSString *)yddLastRecordTime {
    NSString *last_boot_time_ydd = [NSString stringWithFormat:@"%@", @([[NSUserDefaults.standardUserDefaults objectForKey:@"last_record_time_ydd"] integerValue])];
    [NSUserDefaults.standardUserDefaults setObject:[NSString stringWithFormat:@"%ld", (long)[@(NSDate.new.timeIntervalSince1970) integerValue]] forKey:@"last_record_time_ydd"];
    if (last_boot_time_ydd.integerValue <= 0) {
        last_boot_time_ydd = [NSString stringWithFormat:@"%@", @([[NSUserDefaults.standardUserDefaults objectForKey:@"last_record_time_ydd"] integerValue])];
    }
    return last_boot_time_ydd;
}

/// 是否支持VOIP
+ (BOOL)yddAllowsVOIP {
    return CTTelephonyNetworkInfo.new.subscriberCellularProvider.allowsVOIP;
}

/// 网络类型 2G、3G、4G、5G、wifi、other、none
+ (NSString *)yddGetNetworkType {
    struct sockaddr_storage zeroAddress_ydd;
    bzero(&zeroAddress_ydd, sizeof(zeroAddress_ydd));
    zeroAddress_ydd.ss_len = sizeof(zeroAddress_ydd);
    zeroAddress_ydd.ss_family = AF_INET;
    SCNetworkReachabilityRef reachability_ydd = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress_ydd);
    SCNetworkReachabilityFlags flags_ydd;
    BOOL didRetrieveFlags_ydd = SCNetworkReachabilityGetFlags(reachability_ydd, &flags_ydd);
    CFRelease(reachability_ydd);
    if (!didRetrieveFlags_ydd) {
        return @"none";
    }
    BOOL reachable_ydd = ((flags_ydd & kSCNetworkFlagsReachable) != 0);
    BOOL needsConnection_ydd = ((flags_ydd & kSCNetworkFlagsConnectionRequired) != 0);
    if (reachable_ydd && !needsConnection_ydd) { }else{
        return @"none";
    }
    if ((flags_ydd & kSCNetworkReachabilityFlagsConnectionRequired) == kSCNetworkReachabilityFlagsConnectionRequired ) {
        return @"none";
    } else if ((flags_ydd & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN) {
        return [self yddCellularType];
    } else {
        return @"wifi";
    }
}
+ (NSString *)yddCellularType {
    CTTelephonyNetworkInfo * info_ydd = [[CTTelephonyNetworkInfo alloc] init];
    NSString *technology_ydd;
    if (@available(iOS 12.1, *)) {
        if (info_ydd && [info_ydd respondsToSelector:@selector(serviceCurrentRadioAccessTechnology)]) {
            NSDictionary *radio_ydd = [info_ydd serviceCurrentRadioAccessTechnology];
            if (radio_ydd.allKeys.count) {
                technology_ydd = [radio_ydd objectForKey:radio_ydd.allKeys.firstObject];
            } else {
                return @"none";
            }
        } else {
            return @"none";
        }
    } else {
        technology_ydd = info_ydd.currentRadioAccessTechnology;
    }
    if (technology_ydd) {
        if (@available(iOS 14.1, *)) {
            if ([technology_ydd isEqualToString:CTRadioAccessTechnologyNRNSA] || [technology_ydd isEqualToString:CTRadioAccessTechnologyNR]) {
                return @"5G";
            }
        }
        if ([technology_ydd isEqualToString:CTRadioAccessTechnologyLTE]) {
            return @"4G";
        } else if ([technology_ydd isEqualToString:CTRadioAccessTechnologyWCDMA] || [technology_ydd isEqualToString:CTRadioAccessTechnologyHSDPA] || [technology_ydd isEqualToString:CTRadioAccessTechnologyHSUPA] || [technology_ydd isEqualToString:CTRadioAccessTechnologyCDMAEVDORev0] || [technology_ydd isEqualToString:CTRadioAccessTechnologyCDMAEVDORevA] || [technology_ydd isEqualToString:CTRadioAccessTechnologyCDMAEVDORevB] || [technology_ydd isEqualToString:CTRadioAccessTechnologyeHRPD]) {
            return @"3G";
            
        } else if ([technology_ydd isEqualToString:CTRadioAccessTechnologyEdge] || [technology_ydd isEqualToString:CTRadioAccessTechnologyGPRS] || [technology_ydd isEqualToString:CTRadioAccessTechnologyCDMA1x]) {
            return @"2G";
        } else {
            return @"other";
        }
    } else {
        return @"none";
    }
}

/// 手机国家码
+ (NSString *)yddGetMobileCountryCode {
    NSString *mobileCountryCode_ydd = CTTelephonyNetworkInfo.new.subscriberCellularProvider.mobileCountryCode;
    return mobileCountryCode_ydd.length ? mobileCountryCode_ydd : @"";
}

/// 获取载体名
+ (NSString *)yddGetCarrierName {
    NSString *carrierName_ydd = CTTelephonyNetworkInfo.new.subscriberCellularProvider.carrierName;
    return carrierName_ydd.length ? carrierName_ydd : @"";
}

@end


